package middleware

import (
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"kf/models/dao"
	"kf/models/entity"
	"regexp"
	"time"
)

type LoggerSave struct {
	LogDao *dao.LogDao
	Log    *zap.Logger
}

func (loggerSave *LoggerSave) Logger(module uint8, content string) gin.HandlerFunc {
	return func(c *gin.Context) {
		// 开始时间
		startTime := time.Now()
		// 处理请求
		c.Next()
		// 结束时间
		endTime := time.Now()
		// 执行时间
		latencyTime := endTime.Sub(startTime)

		// 请求路由
		reqUri := c.Request.RequestURI
		// 请求IP
		clientIP := c.ClientIP()
		userAgent := c.Request.UserAgent()
		browser, version := parseUserAgent(userAgent)
		method := c.Request.Method
		log := entity.SysLog{
			Module:         module,
			Method:         method,
			Content:        content,
			RequestUri:     reqUri,
			Ip:             clientIP,
			ExecutionTime:  latencyTime.Milliseconds(),
			Browser:        browser,
			BrowserVersion: version,
		}
		// 将日志消息发送到channel
		logChannel <- log
	}
}

// 日志channel
var logChannel = make(chan entity.SysLog, 100) // 一个缓冲区来存储日志消息

// 异步保存日志的goroutine
func (loggerSave *LoggerSave) LogWorker() {
	for log := range logChannel {
		err := loggerSave.LogDao.DB.Save(&log).Error
		if err != nil {
			loggerSave.Log.Error("Error logging:", zap.Error(err))
		}
	}
}

// parseUserAgent 使用正则表达式从User-Agent字符串中提取浏览器名称和版本
func parseUserAgent(userAgentString string) (browserName string, browserVersion string) {
	// 这是一个非常简化的正则表达式，仅用于示例
	// 它可能无法匹配所有浏览器和版本的User-Agent字符串
	// 注意：这个正则表达式假设浏览器名称和版本之间由空格、斜杠或反斜杠分隔
	re := regexp.MustCompile(`(.*?)(?:\s+(?:\d+\.)*\d+(?:\.\d+)*)`)

	// 查找匹配项
	matches := re.FindStringSubmatch(userAgentString)
	if len(matches) > 1 {
		// 假设第一个捕获组是浏览器名称（这通常不是最准确的，但用于示例）
		// 实际上，你可能需要更复杂的逻辑来准确识别浏览器名称和版本
		browserName = matches[1]

		// 由于我们的正则表达式不是专门为了提取版本而设计的，
		// 我们将简单地使用User-Agent字符串中从浏览器名称之后的部分作为版本（非常粗略）
		// 注意：这通常不是提取版本的好方法，因为它可能包含其他信息
		versionStart := regexp.MustCompile(`(?:\s+(?:\d+\.)*\d+(?:\.\d+)*)`).FindStringIndex(userAgentString)
		if versionStart != nil {
			browserVersion = userAgentString[versionStart[0]:]
			// 可能还需要进一步处理browserVersion以去除多余的空格或字符
			browserVersion = regexp.MustCompile(`\s+`).ReplaceAllString(browserVersion, " ")
			browserVersion = regexp.MustCompile(`\s+$`).ReplaceAllString(browserVersion, "")
		}
	}

	// 返回提取的信息（如果找到的话）
	return browserName, browserVersion
}
